/*
 * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// DO NO EDIT! - This file was generated by JavaScriptCore/wasm/generateWasmValidateInlinesHeader.py
// This file is intended to be inlined by WasmValidate.cpp only! It should not be included elsewhere.

#pragma once

#if ENABLE(WEBASSEMBLY)

#include <wtf/StdLibExtras.h>

#if ASSERT_DISABLED
IGNORE_RETURN_TYPE_WARNINGS_BEGIN
#endif

namespace JSC { namespace Wasm {


template<> auto Validate::addOp<OpType::F32Ceil>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: f32.ceil value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::F32DemoteF64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: f32.demote/f64 value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I64TruncSF32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: i64.trunc_s/f32 value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F32ConvertUI64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I64))
        return Unexpected<Result::error_type>("validation failed: f32.convert_u/i64 value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I32Clz>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: i32.clz value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64ConvertUI32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: f64.convert_u/i32 value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I32Ctz>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: i32.ctz value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F32ReinterpretI32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: f32.reinterpret/i32 value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I32TruncSF64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: i32.trunc_s/f64 value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F32Sqrt>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: f32.sqrt value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I32TruncUF64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: i32.trunc_u/f64 value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32Popcnt>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: i32.popcnt value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64Popcnt>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I64))
        return Unexpected<Result::error_type>("validation failed: i64.popcnt value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I64Eqz>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I64))
        return Unexpected<Result::error_type>("validation failed: i64.eqz value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64Clz>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I64))
        return Unexpected<Result::error_type>("validation failed: i64.clz value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Neg>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: f32.neg value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Abs>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: f64.abs value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::F32ConvertSI64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I64))
        return Unexpected<Result::error_type>("validation failed: f32.convert_s/i64 value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::F64ConvertSI32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: f64.convert_s/i32 value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I64Ctz>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I64))
        return Unexpected<Result::error_type>("validation failed: i64.ctz value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F32ConvertUI32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: f32.convert_u/i32 value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Ceil>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: f64.ceil value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::F64Floor>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: f64.floor value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Abs>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: f32.abs value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I32ReinterpretF32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: i32.reinterpret/f32 value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64ConvertSI64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I64))
        return Unexpected<Result::error_type>("validation failed: f64.convert_s/i64 value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I32TruncSF32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: i32.trunc_s/f32 value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64TruncUF64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: i64.trunc_u/f64 value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F64PromoteF32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: f64.promote/f32 value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I64ExtendUI32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: i64.extend_u/i32 value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F64ReinterpretI64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I64))
        return Unexpected<Result::error_type>("validation failed: f64.reinterpret/i64 value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I64TruncSF64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: i64.trunc_s/f64 value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Floor>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: f32.floor value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::F32ConvertSI32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: f32.convert_s/i32 value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::F64ConvertUI64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I64))
        return Unexpected<Result::error_type>("validation failed: f64.convert_u/i64 value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I32Eqz>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: i32.eqz value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64ReinterpretF64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: i64.reinterpret/f64 value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F64Nearest>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: f64.nearest value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::F64Sqrt>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: f64.sqrt value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::F64Trunc>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: f64.trunc value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I32WrapI64>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I64))
        return Unexpected<Result::error_type>("validation failed: i32.wrap/i64 value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F32Trunc>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: f32.trunc value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I32TruncUF32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: i32.trunc_u/f32 value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64TruncUF32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: i64.trunc_u/f32 value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I64ExtendSI32>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != I32))
        return Unexpected<Result::error_type>("validation failed: i64.extend_s/i32 value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F64Neg>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F64))
        return Unexpected<Result::error_type>("validation failed: f64.neg value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Nearest>(ExpressionType value, ExpressionType& result) -> Result
{
    if (UNLIKELY(value != F32))
        return Unexpected<Result::error_type>("validation failed: f32.nearest value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I64ShrS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.shr_s left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.shr_s right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I32Mul>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.mul left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.mul right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32Sub>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.sub left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.sub right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Le>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.le left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.le right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Ne>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.ne left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.ne right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Lt>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.lt left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.lt right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F32Max>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.max left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.max right value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Mul>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.mul left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.mul right value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Div>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.div left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.div right value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::F32Copysign>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.copysign left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.copysign right value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I64And>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.and left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.and right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Ne>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.ne left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.ne right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Gt>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.gt left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.gt right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32DivU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.div_u left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.div_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32DivS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.div_s left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.div_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Ge>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.ge left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.ge right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64GtS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.gt_s left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.gt_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32RemU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.rem_u left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.rem_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64GtU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.gt_u left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.gt_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Div>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.div left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.div right value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Add>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.add left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.add right value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I64Or>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.or left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.or right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I32LeU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.le_u left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.le_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32LeS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.le_s left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.le_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64Ne>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.ne left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.ne right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32And>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.and left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.and right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32LtU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.lt_u left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.lt_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64Rotr>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.rotr left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.rotr right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I32LtS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.lt_s left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.lt_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32Eq>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.eq left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.eq right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Copysign>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.copysign left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.copysign right value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I64Rotl>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.rotl left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.rotl right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Lt>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.lt left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.lt right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Eq>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.eq left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.eq right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F32Le>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.le left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.le right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F32Ge>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.ge left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.ge right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32ShrU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.shr_u left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.shr_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32ShrS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.shr_s left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.shr_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32GeU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.ge_u left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.ge_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32GeS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.ge_s left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.ge_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32Shl>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.shl left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.shl right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32Xor>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.xor left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.xor right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32RemS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.rem_s left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.rem_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Min>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.min left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.min right value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Mul>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.mul left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.mul right value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I64Sub>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.sub left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.sub right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I32Add>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.add left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.add right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Sub>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.sub left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.sub right value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I32Or>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.or left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.or right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64LtU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.lt_u left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.lt_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64LtS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.lt_s left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.lt_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64Xor>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.xor left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.xor right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I64GeU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.ge_u left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.ge_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F32Min>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.min left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.min right value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::I64Mul>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.mul left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.mul right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Sub>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.sub left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.sub right value type mismatch");

    result = F32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Add>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.add left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.add right value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I64GeS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.ge_s left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.ge_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64RemS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.rem_s left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.rem_s right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I64RemU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.rem_u left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.rem_u right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I32Ne>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.ne left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.ne right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F32Eq>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.eq left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.eq right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64Eq>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.eq left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.eq right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64ShrU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.shr_u left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.shr_u right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I64Shl>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.shl left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.shl right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I64DivU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.div_u left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.div_u right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::F32Gt>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F32))
        return Unexpected<Result::error_type>("validation failed: f32.gt left value type mismatch");

    if (UNLIKELY(right != F32))
        return Unexpected<Result::error_type>("validation failed: f32.gt right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32Rotl>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.rotl left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.rotl right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32Rotr>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.rotr left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.rotr right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I32GtU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.gt_u left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.gt_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64DivS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.div_s left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.div_s right value type mismatch");

    result = I64;
    return { };
}

template<> auto Validate::addOp<OpType::I32GtS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I32))
        return Unexpected<Result::error_type>("validation failed: i32.gt_s left value type mismatch");

    if (UNLIKELY(right != I32))
        return Unexpected<Result::error_type>("validation failed: i32.gt_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::F64Max>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != F64))
        return Unexpected<Result::error_type>("validation failed: f64.max left value type mismatch");

    if (UNLIKELY(right != F64))
        return Unexpected<Result::error_type>("validation failed: f64.max right value type mismatch");

    result = F64;
    return { };
}

template<> auto Validate::addOp<OpType::I64LeU>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.le_u left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.le_u right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64LeS>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.le_s left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.le_s right value type mismatch");

    result = I32;
    return { };
}

template<> auto Validate::addOp<OpType::I64Add>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result
{
    if (UNLIKELY(left != I64))
        return Unexpected<Result::error_type>("validation failed: i64.add left value type mismatch");

    if (UNLIKELY(right != I64))
        return Unexpected<Result::error_type>("validation failed: i64.add right value type mismatch");

    result = I64;
    return { };
}


auto Validate::load(LoadOpType op, ExpressionType pointer, ExpressionType& result, uint32_t) -> Result
{
    if (UNLIKELY(!hasMemory()))
        return Unexpected<Result::error_type>("validation failed: load instruction without memory");

    switch (op) {

    case LoadOpType::I64Load32U: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.load32_u pointer type mismatch");

        result = I64;
        return { };
    }
    case LoadOpType::I64Load32S: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.load32_s pointer type mismatch");

        result = I64;
        return { };
    }
    case LoadOpType::I32Load16S: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i32.load16_s pointer type mismatch");

        result = I32;
        return { };
    }
    case LoadOpType::I32Load16U: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i32.load16_u pointer type mismatch");

        result = I32;
        return { };
    }
    case LoadOpType::I64Load: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.load pointer type mismatch");

        result = I64;
        return { };
    }
    case LoadOpType::F64Load: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: f64.load pointer type mismatch");

        result = F64;
        return { };
    }
    case LoadOpType::I32Load8S: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i32.load8_s pointer type mismatch");

        result = I32;
        return { };
    }
    case LoadOpType::I32Load8U: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i32.load8_u pointer type mismatch");

        result = I32;
        return { };
    }
    case LoadOpType::I32Load: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i32.load pointer type mismatch");

        result = I32;
        return { };
    }
    case LoadOpType::F32Load: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: f32.load pointer type mismatch");

        result = F32;
        return { };
    }
    case LoadOpType::I64Load8U: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.load8_u pointer type mismatch");

        result = I64;
        return { };
    }
    case LoadOpType::I64Load8S: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.load8_s pointer type mismatch");

        result = I64;
        return { };
    }
    case LoadOpType::I64Load16S: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.load16_s pointer type mismatch");

        result = I64;
        return { };
    }
    case LoadOpType::I64Load16U: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.load16_u pointer type mismatch");

        result = I64;
        return { };
    }
    }
    ASSERT_NOT_REACHED();
}

auto Validate::store(StoreOpType op, ExpressionType pointer, ExpressionType value, uint32_t) -> Result
{
    if (UNLIKELY(!hasMemory()))
        return Unexpected<Result::error_type>("validation failed: store instruction without memory");

    switch (op) {

    case StoreOpType::I64Store16: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.store16 pointer type mismatch");

        if (UNLIKELY(value != I64))
            return Unexpected<Result::error_type>("validation failed: i64.store16 value type mismatch");

        return { };
    }
    case StoreOpType::I64Store8: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.store8 pointer type mismatch");

        if (UNLIKELY(value != I64))
            return Unexpected<Result::error_type>("validation failed: i64.store8 value type mismatch");

        return { };
    }
    case StoreOpType::I32Store: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i32.store pointer type mismatch");

        if (UNLIKELY(value != I32))
            return Unexpected<Result::error_type>("validation failed: i32.store value type mismatch");

        return { };
    }
    case StoreOpType::I32Store16: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i32.store16 pointer type mismatch");

        if (UNLIKELY(value != I32))
            return Unexpected<Result::error_type>("validation failed: i32.store16 value type mismatch");

        return { };
    }
    case StoreOpType::F32Store: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: f32.store pointer type mismatch");

        if (UNLIKELY(value != F32))
            return Unexpected<Result::error_type>("validation failed: f32.store value type mismatch");

        return { };
    }
    case StoreOpType::I64Store: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.store pointer type mismatch");

        if (UNLIKELY(value != I64))
            return Unexpected<Result::error_type>("validation failed: i64.store value type mismatch");

        return { };
    }
    case StoreOpType::F64Store: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: f64.store pointer type mismatch");

        if (UNLIKELY(value != F64))
            return Unexpected<Result::error_type>("validation failed: f64.store value type mismatch");

        return { };
    }
    case StoreOpType::I32Store8: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i32.store8 pointer type mismatch");

        if (UNLIKELY(value != I32))
            return Unexpected<Result::error_type>("validation failed: i32.store8 value type mismatch");

        return { };
    }
    case StoreOpType::I64Store32: {
        if (UNLIKELY(pointer != I32))
            return Unexpected<Result::error_type>("validation failed: i64.store32 pointer type mismatch");

        if (UNLIKELY(value != I64))
            return Unexpected<Result::error_type>("validation failed: i64.store32 value type mismatch");

        return { };
    }
    }
    ASSERT_NOT_REACHED();
}

} } // namespace JSC::Wasm

#if ASSERT_DISABLED
IGNORE_RETURN_TYPE_WARNINGS_END
#endif

#endif // ENABLE(WEBASSEMBLY)

